﻿// ********************************
// 2010.11.02
// 拓扑节点控件
// Author:卢融凯
// ********************************
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Net;
using SManage.Infrastructure;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Reflection;
using SManage.Model;
using System.Linq;
using System.Threading;

namespace SManage.Control
{
    [Serializable]
    public sealed partial class TopologyNode : UserControl,ITopologyNode,ISerializable
    {
        private IStation _station;
        private IList<IPAddress> _interfaceList;
        private IList<ITopologyNode> _linkList;
        public event EventHandler<DeviceManageRaisedArgs> DeviceManageRaised;

        private void OnDeviceManage(DeviceManageRaisedArgs e) {
            var handle = Interlocked.CompareExchange(ref DeviceManageRaised, null, null);
            if (handle != null) {
                handle(this, e);
            }
        }

        public TopologyNode()
        {
            InitializeComponent();
            InitializeStation();
            DoubleBuffered = true; 
        }

        private void InitializeStation() {
            StationImage.Image = Station.Image;
            StationName.Text = Station.Name;
        }

        public void SetText(String text) {
            StationName.Text = text;
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            var min = Math.Min(Width, Height);
            AdjustSize(min);
        }

        private void AdjustSize(int minSide) {
            if (minSide < 45) { minSide = 45; }
            Width = minSide;
            Height = minSide + 22;

            StationImage.Width = minSide;
            StationImage.Height = minSide;

            StationName.Width = minSide;
            StationName.Height = 12;

            StationName.Location = new Point(0, minSide + 5);
        }

        #region Drag and drop
        private Boolean _moving;
        private Point _mouseStartPos;
        private void AllMouseDown(object sender, MouseEventArgs e)
        {
            _moving = true;
            _mouseStartPos = e.Location;
        }

        private void AllMouseMove(object sender, MouseEventArgs e)
        {
            Cursor = Cursors.SizeAll;
            if (_moving) {
                var newPoint = new Point(e.X - _mouseStartPos.X, e.Y - _mouseStartPos.Y);
                Location = new Point(
                    Location.X + newPoint.X,
                    Location.Y + newPoint.Y);
            }
            OnPaint(null);
        }

        private void AllMouseUp(object sender, MouseEventArgs e) {
            _moving = false;
        }
        #endregion

        #region ITopologyData

        /// <summary>
        /// 节点所包含的设备
        /// </summary>
        public IStation Station {
            get { return _station ?? (_station = new Router()); }
            set {
                _station = value;
                InitializeStation();
            }
        }

        /// <summary>
        /// 设备的接口列表
        /// </summary>
        public IList<IPAddress> InterfaceList {
            get { return _interfaceList ?? (_interfaceList = new List<IPAddress>()); }
            set {
                _interfaceList = value;
            }
        }

        /// <summary>
        /// 具体的链路列表
        /// </summary>
        public IList<ITopologyNode> LinkList {
            get { return _linkList ?? (_linkList = new List<ITopologyNode>()); }
            set {
                _linkList = value;
            }
        }

        public Point Center {
            get {
                return new Point(
                    Location.X + Width / 2,
                    Location.Y + Width / 2);
            }
        }

        #endregion

        [SecurityPermission(SecurityAction.Demand,SerializationFormatter = true)]
        private TopologyNode(SerializationInfo info, StreamingContext context) {
            _station = (IStation)info.GetValue("station",typeof(IStation));
            _interfaceList = (IList<IPAddress>)info.GetValue("interfaceList",typeof(IList<IPAddress>));
            _linkList = (IList<ITopologyNode>)info.GetValue("linkList",typeof(IList<ITopologyNode>));
            InitializeComponent();
            InitializeStation();
            Size = (Size)info.GetValue("size", typeof(Size));
            Location = (Point)info.GetValue("location", typeof(Point));

        }
        public void GetObjectData(SerializationInfo info, StreamingContext context) {
            info.AddValue("station",_station);
            info.AddValue("interfaceList",_interfaceList);
            info.AddValue("linkList",_linkList);
            info.AddValue("size", Size);
            info.AddValue("location", Location);
            //info.AddValue("stationImage.Image", StationImage.Image);
        }

        private void 系统表ToolStripMenuItem_Click(object sender, EventArgs e) {
            using (var entity = new SManageEntities()) {
                var deviceIp = _interfaceList.First().ToString();

                var systems = from ips in entity.Mib2_ip_ipAddrEntry
                              where ips.ipAdEntAddr.Trim() == deviceIp
                              let system = ips.Mib2_ip.Devices.Mib2_system
                              select new {
                                  系统描述 = system.sysDescr,
                                  启动时间 = system.sysUpTime,
                                  联系方式 = system.sysContact,
                                  位置 = system.sysLocation,
                                  服务代码 = system.sysServices
                              };
                ShowTableForm(systems);
            }
        }

        private void 接口表ToolStripMenuItem_Click(object sender, EventArgs e) {
            using (var entity = new SManageEntities()) {
                var deviceIp = _interfaceList.First().ToString();

                var interfaces = from ips in entity.Mib2_ip_ipAddrEntry
                                 where ips.ipAdEntAddr.Trim() == deviceIp
                                 let ifts = ips.Mib2_ip.Devices.Mib2_interfaces.Mib2_interfaces_ifEntry
                                 from ift in ifts
                                 select new {
                                     接口索引 = ift.ifIndex,
                                     接口描述 = ift.ifDescr,
                                     接口类型 = ift.ifType,
                                     Mtu = ift.ifMtu,
                                     速率 = ift.ifSpeed,
                                     物理地址 = ift.ifPhysAddress
                                 };
                ShowTableForm(interfaces);
            }
        }

        private void 地址表ToolStripMenuItem_Click(object sender, EventArgs e) {
            using (var entity = new SManageEntities()) {
                var deviceIp = _interfaceList.First().ToString();

                var ipAddrs = from ips in entity.Mib2_ip_ipAddrEntry
                              where ips.ipAdEntAddr.Trim() == deviceIp
                              let ipaddrs = ips.Mib2_ip.Devices.Mib2_ip.Mib2_ip_ipAddrEntry
                              from ipaddr in ipaddrs
                              select new {
                                  接口索引 = ipaddr.ipAdEntIndex,
                                  IP地址 = ipaddr.ipAdEntAddr,
                                  子网掩码 = ipaddr.ipAdEntNetMask,
                                  广播地址 = ipaddr.ipAdEntBcastAddr
                              };
                ShowTableForm(ipAddrs);
            }
        }

        private void 路由表ToolStripMenuItem_Click(object sender, EventArgs e) {
            using (var entity = new SManageEntities()) {
                var deviceIp = _interfaceList.First().ToString();

                var ipRoutes = from ips in entity.Mib2_ip_ipAddrEntry
                               where ips.ipAdEntAddr.Trim() == deviceIp
                               let iproutes = ips.Mib2_ip.Devices.Mib2_ip.Mib2_ip_ipRouteEntry
                               from iproute in iproutes
                               select new {
                                   目标路由 = iproute.ipRouteDest,
                                   下一跳地址 = iproute.ipRouteNextHop,
                                   路由类型 = iproute.ipRouteType,
                                   路由协议 = iproute.ipRouteProto,
                                   路由信息 = iproute.ipRouteInfo

                               };
                ShowTableForm(ipRoutes);
            }
        }

        private void 地址转发表ToolStripMenuItem_Click(object sender, EventArgs e) {
            using (var entity = new SManageEntities()) {
                var deviceIp = _interfaceList.First().ToString();

                var ipNats = from ips in entity.Mib2_ip_ipAddrEntry
                             where ips.ipAdEntAddr.Trim() == deviceIp
                             let ipnats = ips.Mib2_ip.Devices.Mib2_ip.Mib2_ip_ipNetToMediaEntry
                             from ipnat in ipnats
                             select new {
                                 物理地址 = ipnat.ipNetToMediaPhysAddress,
                                 网络地址 = ipnat.ipNetToMediaNetAddress,
                                 类型 = ipnat.ipNetToMediaType

                             };
                ShowTableForm(ipNats);
            }
        }

        private void ShowTableForm(object data) {
            var form = new TableDetails();
            form.dataGridView.DataSource = data;
            form.ShowDialog();   
        }

        private void 接口流量ToolStripMenuItem_Click(object sender, EventArgs e) {
            using (var entity = new SManageEntities()) {
                var deviceIp = _interfaceList.First().ToString();

                var device = from ips in entity.Mib2_ip_ipAddrEntry
                             where ips.ipAdEntAddr.Trim() == deviceIp
                             select ips.Mib2_ip.Devices;
                try {
                    var interfaceFlow = InterfaceFlowCalc.GetDeviceFlow(device.First());
                } catch {
                    MessageBox.Show("连接超时！", "失败", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
        }

        private void 设备管理ToolStripMenuItem_Click(object sender, EventArgs e) {
            using (var entity = new SManageEntities()) {
                var deviceIp = _interfaceList.First().ToString();

                var device = from ips in entity.Mib2_ip_ipAddrEntry
                             where ips.ipAdEntAddr.Trim() == deviceIp
                             select ips.Mib2_ip.Devices;
                OnDeviceManage(new DeviceManageRaisedArgs { Target = device.First() });
            }             
        }
    }
}
